/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tubes1sister.peerConnection;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import tubes1sister.peerConnection.PeerInfo;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;
import tubes1sister.peerConnection.message.Handshake;
import tubes1sister.peerConnection.message.MessageFlow;
import tubes1sister.tools.SHA1Utility;
import tubes1sister.tools.debug;

/**
 *
 * @author ZAKIY FIRDAUS ALFIKR
 */
public class clientHandler extends Thread {

    //memiliki PeerInfo untuk tempat connect dan mencari pieces ke berapa
    public PeerInfo info;
    //memiliki id
    public int id;
    //memiliki variable apakah sudah selese ato lum
    public boolean isFinished;
    /*
    memiliki status selesai
     * Jika status selesai = 1 ==> selesai dengan sukses
     * Jika status selesai != 1 ==> selesainya gara-gara sesuatu yang tidak diharapkan
     */
    public int statusSelesai;
    //memiliki socket
    public Socket skt;
    //memiliki array of byte yang akan di download
    byte[] download;
    @Override
    public void run() {
        try {
            skt = new Socket(info.ip, Integer.parseInt(info.port));            
            DataInputStream dis = new DataInputStream(skt.getInputStream());
            DataOutputStream dos = new DataOutputStream(skt.getOutputStream());
            //kirimkan pesan handshake pertama kali
            Handshake hs = new Handshake(info.filename, info.indexPieces);
            String handshakemessage = hs.generateMessage();
            byte[] hasil = handshakemessage.getBytes();
            dos.write(hasil);
            //out.println(hs.generateMessage());
            dos.flush();
            //tunggu balasan dari peer satunya
            byte[] bitfield = new byte[8];
            int read = dis.read(bitfield);
            String bitfieldmessage = new String(bitfield);
            if (bitfieldmessage.indexOf("yes") == -1) {
                //hentikan koneksi return
                isFinished = true;
                statusSelesai = -999;
                return;
            } else {
                //berarti dia memiliki file yang diinginkan
                //kirim request
                String request = MessageFlow.generateRequestMessage(info.indexPieces);
                byte[] requestbyte = request.getBytes();
                //kirim ke sana
                dos.write(requestbyte);
                dos.flush();
                //tunggu balasan                
                dis.read(download);
                //cek hashnya
                if(info.indexPieces == (info.panjangFile / info.pieceLenght)){
                        //unpadding
                        download = Arrays.copyOf(download, (info.panjangFile% info.pieceLenght));
                  }    
                String shaPieces = SHA1Utility.getSHA1(SHA1Utility.convertToHex(download));
                if(shaPieces.equals(info.nilaiHash)){
                    //berarti sukses
                    //cek apakah dia piece terakhir
                                   
                    isFinished = true;
                    statusSelesai = 1;
                }
                
            }          
        } catch (UnknownHostException ex) {
            isFinished = true;
            statusSelesai = -999;
            Logger.getLogger(clientHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            isFinished = true;
            statusSelesai = -999;
            Logger.getLogger(clientHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex){
            isFinished = true;
            statusSelesai = -999;
            Logger.getLogger(clientHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public clientHandler(PeerInfo p, int id) {
        this.info = p;
        this.id = id;
        isFinished = false;
        download = new byte[info.pieceLenght];
    }
}
